#include <windows.h>
#include "resource.h" 
#include<stdlib.h>
#include "global.h"
#include "gap_buffer.h"
#include "linked_list.h"
#include "random.h"


//struct gap_buffer
//{
//	char *buffer;
//	// o matrice dinamica (vector de caractere),alocata dinamic
//	//in care vom memorar textul
//	char *head_gap;
//	//pointer la adreasa de inceput a gap-ului
//	char *after_gap;
//	//pointer la urmatoarea adresa inafara gap-ului
//	char *cursor;
//	//pointer la pozitia cursorului
//	//nu il vom folosi deoarece user-ul da pozitia
//	//pe care se va efectua o anumita operatie
//	int DIM;//dimensiunea blocului de memorie (a buffer-ului);
//	int dim_begin;//dimensiunea segmentului de inceput
//	int dim_end;//dimensiunea segmetului de dupa gap
//	int dim_gap;//dimensiunea gap-ului
//}TEXT_EDITOR;
//ddddd
HINSTANCE hinst;
BOOL CALLBACK dialog1 (HWND hwnd_dialog, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK AFISARE_TEXT(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK dialog_rand(HWND hwnd_dialog_r, UINT Message, WPARAM wParam, LPARAM lParam);


int returnare_continut(HWND hwnd,char **sir,int Box_id);

bool verificare_integer(char *cuv)
{
	char *verificator="1234567890";
	for(int i=0;i<strlen(cuv);i++)
		if(!strchr(verificator,cuv[i]))
			return 0;
	return 1;
}
		

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASSEX wc;
	//HWND hwnd;
	HFONT hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	HWND hWndButton,altbuton;
	MSG Msg;

	wc.cbSize		 = sizeof(WNDCLASSEX);
	wc.style		 = CS_HREDRAW|CS_VREDRAW;
	wc.lpfnWndProc	 = WndProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
	wc.lpszClassName = g_szClassName;
	wc.hIconSm		 = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);

	if(!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Window Registration Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
		g_szClassName,
		"GAP_BUFFER EVALUATOR",
		WS_OVERLAPPEDWINDOW&~WS_MAXIMIZEBOX,
		CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
		NULL, NULL, hInstance, NULL);

	if(hwnd == NULL)
	{
		MessageBox(NULL, "Window Creation Failed!", "Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}
	hinst=hInstance;
	v_vector.secondbuff=NULL;

	hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
	 hWndButton=CreateWindowEx(NULL,
				"BUTTON",
				"VIZUALIZARE GAP BUFFER",
				WS_TABSTOP|WS_VISIBLE|
				WS_CHILD|BS_DEFPUSHBUTTON,
				250,
				600,
				400,
				80,
				hwnd,
				(HMENU)IDC_MAIN_BUTTON,
				GetModuleHandle(NULL),
				NULL);
			SendMessage(hWndButton,
				WM_SETFONT,
				(WPARAM)hfDefault,
				MAKELPARAM(FALSE,0));
	hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    altbuton=CreateWindowEx(NULL,
				"BUTTON",
				"DEZACTIVARE VIZUALIZATOR",
				WS_TABSTOP|WS_VISIBLE|
				WS_CHILD|BS_DEFPUSHBUTTON,
				651,
				600,
				400,
				80,
				hwnd,
				(HMENU)IDC_SECOND_BUTTON,
				GetModuleHandle(NULL),
				NULL);
			SendMessage(hWndButton,
				WM_SETFONT,
				(WPARAM)hfDefault,
				MAKELPARAM(FALSE,0));

	ShowWindow(hwnd,SW_MAXIMIZE);
	UpdateWindow(hwnd);

	superbuff=(char *)calloc(sizeof(char),(TEXT_EDITOR.DIM+1));

	////////////////////////////////////////////
	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	free(TEXT_EDITOR.buffer);
	elibmem(&prim);
	if(superbuff!=NULL)
		free(superbuff);

	return Msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	HWND d1,d2,Rand_X;
    PAINTSTRUCT ps;
    HDC hdc;
	HBRUSH Brush_Gap,Brush_Linked_List,Brush_Platforma;
	double coeficient=0;		//coeficientul cu care un timp este mai mare decat celalalt
	float y;	// auxiliar pentru coordonate
	char *ana="12345";
	int pseudogap=19,nr_gap=10;

	int wmId, wmEvent;
    RECT clientRect;
    RECT textRect;
    HRGN bgRgn;
    HBRUSH hBrush;
    HPEN hPen;
	int x=10,i,j,val_vechi,cont,var,nr_adaugate;
	static int nr1=28,nr2=0;
	int k=p_buff,nr_cas=10,pre=19,start;
	int nr_val=p_buff,contor1,contor2;
	const char *ch="R";
	const char *chd=" ";
	const char *letter;
	int xa=865 , ya=495 , xb=865 , yb=510 , xd=1285 , yd=495 , xc=1285 , yc=510;		/// coordonate 
	int xe=1335 , ye=450 , xf=1335 , yf = 435 , xg=925 , yg=435 , xh=920, yh=475 , xi=920 , yi=105, bucla;
	char t_gap[100],t_list[100];
	
	switch(Message)
	{
	case WM_CREATE:
		MessageBox(hwnd,"Incepe aplicatia GAP-BUFFER EVALUATOR\nVizualizatorul gap-buffer-ului este inactiv initial.\n         Bucurati-va de programare!!!","Mesaj",MB_ICONEXCLAMATION);
	break;

	case WM_COMMAND:
			switch(LOWORD(wParam))
			{
				case IDC_MAIN_BUTTON:
					MessageBox(hwnd,"Vizualizatorul grafic a fost activat.","Mesaj",MB_OK);
					ACTIV=1;
				break;
				case IDC_SECOND_BUTTON:
					MessageBox(hwnd,"Vizualizatorul grafic a fost dezactivat.","Mesaj",MB_OK);
					ACTIV=0;
				break;
				case ID_SET:
					d2=CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OLE_PROPPAGE_LARGE),hwnd,dialog1);
					ShowWindow(d2,SW_NORMAL);
					 if (d2!=NULL)
                        {
                                ShowWindow(d2,SW_SHOW);
                        }
                        else
                        {
                                MessageBox(hwnd,"Eroare la crearea dialogului 1","EROARE",MB_OK | MB_ICONERROR);
                        }
					break;
				case ID_RAND:
					SendMessage(hwnd,RESET_GRAFIC,0,0);
					DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG2), NULL,dialog_rand);
					//DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, AFISARE_TEXT);
					SendMessage(hwnd,WM_COMMAND,ID_AFISARE,0);
					break;
				case ID_AFISARE:
					{
						//SIZE_SAU_AF=1;
						//DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, AFISARE_TEXT);
						SendMessage(hwnd,RESET_GRAFIC,0,0);
					hdc = GetDC(hwnd);
					Brush_Gap  = CreateSolidBrush(RGB(154,0,3));
					Brush_Linked_List    = CreateSolidBrush(RGB(86, 115, 40));
					POINT  Pt[4];
					if(timp_gap==0 || timp_liste==0)
					{
						MessageBox(hwnd,"Timpul a fost resetat la zero.","Info",MB_OK);
						break;
					}

					GRAFIC_ACTIV=1;
			//------------afisarea timpului----------------------------------------------------
					sprintf_s(t_gap,"%f",timp_gap);
					sprintf_s(t_list,"%f",timp_liste);

					SetBkColor(hdc, RGB(255,255,1255));
					SetRect(&textRect,860,50,1060,80);
					DrawText(hdc,TEXT("TIMP GAP-BUFFER SECUNDE"),-1,&textRect, DT_CENTER | DT_NOCLIP);

					SetBkColor(hdc, RGB(255,255,1255));
					SetRect(&textRect,1140,50,1300,80);
					DrawText(hdc,TEXT("TIMP LISTE SECUNDE"),-1,&textRect, DT_CENTER | DT_NOCLIP);

					x=910;
					for(i=0;i<strlen(t_gap) && i<20;i++)
					{
						letter=(const char *)(t_gap+i);
						SetBkColor(hdc, RGB(255,255,255));
						SetRect(&textRect,x,81,x+11,105);
						DrawText(hdc,TEXT(letter),1,&textRect, DT_CENTER | DT_NOCLIP);
						x=x+11;
					}

					
					x=1180;
					for(i=0;i<strlen(t_gap) && i<20;i++)
					{
						letter=(const char *)(t_list+i);
						SetBkColor(hdc, RGB(255,255,1255));
						SetRect(&textRect,x,81,x+11,105);
						DrawText(hdc,TEXT(letter),1,&textRect, DT_CENTER | DT_NOCLIP);
						x=x+11;
					}
				//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  s-a incheiat afisarea timpului  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//=======================================================================================================
			// desenarea graficului
					Brush_Gap  = CreateSolidBrush(RGB(255,0,0));
					Brush_Linked_List = CreateSolidBrush(RGB(0, 51, 255));
					Brush_Platforma = CreateSolidBrush(RGB(255, 235, 0));
		//===============================================================
					hPen = CreatePen(PS_SOLID,1.8,RGB(0,0,0));     // platforma 
					SelectObject(hdc, hPen);
					SelectObject(hdc, Brush_Platforma);			
					Pt[0].x=xa; Pt[0].y=ya;
					Pt[1].x=xb; Pt[1].y=yb;
					Pt[2].x=xc; Pt[2].y=yc;
					Pt[3].x=xd; Pt[3].y=yd;
					Polygon(hdc, Pt, 4);
					Pt[0].x=xc; Pt[0].y=yc;
					Pt[1].x=xd; Pt[1].y=yd;
					Pt[2].x=xf; Pt[2].y=yf;
					Pt[3].x=xe; Pt[3].y=ye;
					Polygon(hdc, Pt, 4);
					Pt[0].x=xa; Pt[0].y=ya;
					Pt[1].x=xd; Pt[1].y=yd;
					Pt[2].x=xf; Pt[3].y=yf;
					Pt[3].x=xg; Pt[2].y=yg;
					Polygon(hdc, Pt, 4);
		//=================================================================
					hPen = CreatePen(PS_SOLID,2.5,RGB(0,0,0));	// axa
					SelectObject(hdc, hPen);
					MoveToEx(hdc, xh, yh, NULL);
					LineTo(hdc, xi, yi);
					LineTo(hdc, xi-7, yi+9);
					MoveToEx(hdc, xi, yi, NULL);
					LineTo(hdc, xi+7, yi+9);
					MoveToEx(hdc, xh, yh, NULL);
					bucla=6;
					while(bucla<=320)
					{
						if(bucla%30==0)
						{
							MoveToEx(hdc, xh-7, yh-bucla, NULL);
							LineTo(hdc, xi+7, yh-bucla);
						}
						else
						{
							MoveToEx(hdc, xh-5, yh-bucla, NULL);
							LineTo(hdc, xi+5, yh-bucla);
						}
						bucla+=6;
					}
					hPen = CreatePen(PS_SOLID,0.9,RGB(0,0,0));
					SelectObject(hdc, hPen);

		//=================================================================
					if(timp_gap > timp_liste)			// daca timpul gap-ului este mai mare desenam graficul gapului la maxim, iar 
					{									// cel al listelor in functie de cat e mai mic
						SelectObject(hdc, Brush_Gap);			
						Pt[0].x=940; Pt[0].y=480;
						Pt[1].x=940; Pt[1].y=160;
						Pt[2].x=1000; Pt[2].y=160;
						Pt[3].x=1000; Pt[3].y=480;
						Polygon(hdc, Pt, 4);
						Pt[0].x=940; Pt[0].y=160;
						Pt[1].x=1000; Pt[1].y=160;
						Pt[2].x=1015; Pt[3].y=145;
						Pt[3].x=955; Pt[2].y=145;
						Polygon(hdc, Pt, 4);
						Pt[3].x=1000; Pt[3].y=160;
						Pt[2].x=1015; Pt[2].y=145;
						Pt[1].x=1015; Pt[1].y=465;
						Pt[0].x=1000; Pt[0].y=480;
						Polygon(hdc, Pt, 4);

						coeficient=(320 * timp_liste)/timp_gap;		// 320 reprezinta inaltimea maxima a graficului cel mai mare 
						y=(float)(480 - coeficient);
							
						SelectObject(hdc, Brush_Linked_List);			// desenam graficul timpului scos de liste
						Pt[0].x=1180; Pt[0].y=480;
						Pt[1].x=1240; Pt[1].y=480;
						Pt[2].x=1240; Pt[2].y=y;
						Pt[3].x=1180; Pt[3].y=y;
						Polygon(hdc, Pt, 4);
						Pt[0].x=1240; Pt[0].y=y;
						Pt[1].x=1180; Pt[1].y=y;
						Pt[2].x=1195; Pt[2].y=y-15;
						Pt[3].x=1255; Pt[3].y=y-15;
						Polygon(hdc, Pt, 4);
						Pt[0].x=1255; Pt[0].y=y-15;
						Pt[1].x=1255; Pt[1].y=465;
						Pt[2].x=1240; Pt[2].y=480;
						Pt[3].x=1240; Pt[3].y=y;
						Polygon(hdc, Pt, 4);
					}			//=====================================================
					else							// cazul in care listele au timpul mai mare
					{
						SelectObject(hdc, Brush_Linked_List);			// desenam graficul listelor la maxim, iar cel al gapului in functie de cat e mai mic
						Pt[0].x=1180; Pt[0].y=480;
						Pt[1].x=1180; Pt[1].y=160;
						Pt[2].x=1240; Pt[2].y=160;
						Pt[3].x=1240; Pt[3].y=480;
						Polygon(hdc, Pt, 4);
						Pt[0].x=1180; Pt[0].y=160;
						Pt[1].x=1240; Pt[1].y=160;
						Pt[2].x=1255; Pt[3].y=145;
						Pt[3].x=1195; Pt[2].y=145;
						Polygon(hdc, Pt, 4);
						Pt[3].x=1240; Pt[3].y=160;
						Pt[2].x=1255; Pt[2].y=145;
						Pt[1].x=1255; Pt[1].y=465;
						Pt[0].x=1240; Pt[0].y=480;
						Polygon(hdc, Pt, 4);

						coeficient=(320 * timp_gap)/timp_liste;		// 320 reprezinta inaltimea maxima a graficului cel mai mare 
						y=(float)(480 - coeficient);
							
						SelectObject(hdc, Brush_Gap);			// desenam graficul timpului scos de gap_buffer
						Pt[0].x=940; Pt[0].y=480;
						Pt[1].x=1000; Pt[1].y=480;
						Pt[2].x=1000; Pt[2].y=y;
						Pt[3].x=940; Pt[3].y=y;
						Polygon(hdc, Pt, 4);
						Pt[0].x=1000; Pt[0].y=y;
						Pt[1].x=940; Pt[1].y=y;
						Pt[2].x=955; Pt[2].y=y-15;
						Pt[3].x=1015; Pt[3].y=y-15;
						Polygon(hdc, Pt, 4);
						Pt[0].x=1015; Pt[0].y=y-15;
						Pt[1].x=1015; Pt[1].y=465;
						Pt[2].x=1000; Pt[2].y=480;
						Pt[3].x=1000; Pt[3].y=y;
						Polygon(hdc, Pt, 4);
					}
					
					DeleteObject(hPen);	DeleteObject(Brush_Linked_List);
					DeleteObject(Brush_Platforma); DeleteObject(Brush_Gap);

					if(SIZE_SAU_AF==1)
						DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, AFISARE_TEXT);
					SIZE_SAU_AF=1;
					break;	
					}
				case ID_TEXT:
					DialogBox(hinst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, AFISARE_TEXT);
				break;
//				case ID_HELP_DE_HELP:
//
////					MessageBox(hwnd, vp, "Woo!", MB_OK);
//				break;
				case ID_CEINSEAMNA_RANDOM:
					MessageBox(hwnd,"Prin apasare RANDOM din meniul derulant utilizatorul va putea sa efectueze un numar mare de operatii pe un gap_construit pe baza unui fisier.\nSfaturi:\n Se recomanda ca pentru un numar mare de operatii sa se aleaga un fisier mare deoarece gap-ul va fluctua mai mult."," DESPRE RANDOM",MB_ICONINFORMATION);
					break;
				case ID_SET22:
					MessageBox(hwnd,"Utilizatorul isi alege felul si modul in care vor fi implementate operatiile asupa gap-buffer-ului.","SET OPERATII",MB_ICONINFORMATION);
					break;
				case ID_CEINSEAMNA_AFISARE:
					MessageBox(hwnd,"Utilizatorul poate vedea cum s-a modificat textul adaugat de el","AFISARE",MB_ICONINFORMATION);
					break;
				case ID_HELP_ALTERASPUNSURI:
					//system("c:\internet explorer");
					break;
				case ID_AFISARE2:
					MessageBox(hwnd,"Se va afisa un grafic cu timpii pentru cele doua structuri de date.\n","INFO-AFISARE GRAFIC",MB_ICONINFORMATION);
					break;
				case ID_VIZ:
					MessageBox(hwnd,"Utilizatorul poate vedea cum se desfasoara operatiile asupra gap-buffer-ului.\nNerecomandat pentru multe operatii deoarece devine plictisitor.","VIZUALIZATOR",MB_ICONINFORMATION);
					break;
				case ID_RASPUNS:
					MessageBox(hwnd,"1.Programul nu va raspunde la comenzi daca pe ecran se executa alte operatii.\n2.Pentru vizualizator culoarea rosie reprezinta gap-ul,adica portiunea in care se vor efectua inserarile.\n3.Daca mai sunt bug-uri nu va panicati, le vom gasi, rezolva si trimite update-uri.\n4.Bucurati-va de programare!!!","",MB_ICONINFORMATION);
					break;
			}
			break;
	//----------------------actualizarea ecranului dupa ce user-ul a inchis dialogul------
	case RESET_GRAFIC:
			//GRAFIC_ACTIV=0;
			hdc=GetDC(hwnd);
			GetClientRect(hwnd,&clientRect);
			bgRgn=CreateRectRgnIndirect(&clientRect);
			hBrush=CreateSolidBrush(RGB(255,255,255));
			hPen=CreatePen(PS_DOT,1,RGB(255,255,255));
			//SelectObject(hdc,CreateSolidBrush(RGB(255,255,255)));
			
			//Rectangle(hdc,900,20,1350,500);
			SelectObject(hdc,CreateSolidBrush(RGB(255,255,255)));
			hPen = CreatePen(PS_DOT,2,RGB(255,255,255));//perimetrul dreptunghiurilor
			SelectObject(hdc, hPen);
			SetBkColor(hdc, RGB(255,255,255));
			Rectangle(hdc,850,18,1400,520);

			DeleteObject(hBrush);
			DeleteObject(hPen);
			GetStockObject(WHITE_BRUSH);
			GetStockObject(DC_PEN);
		break;
				//----------------------------------------------------------------------------------------------
	case COMANDA:
			{
				buffer_desenat=1;
				hdc=GetDC(hwnd);
				GetClientRect(hwnd,&clientRect);
				bgRgn=CreateRectRgnIndirect(&clientRect);
				hBrush=CreateSolidBrush(RGB(255,255,255));
				hPen=CreatePen(PS_DOT,2,RGB(0,255,0));
				SelectObject(hdc,CreateSolidBrush(RGB(255,255,0)));
				//deja=0;
				if(ACTIV==0)
				{
					x=0;
					if(deja)
						break;
					for(i=0;i<28;i++)
						{
							SelectObject(hdc,CreateSolidBrush(RGB(0,250,0)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(0,255,0));
							Rectangle(hdc,x,530,x+47,586);
							Sleep(300);
							x=x+48;
						}
					deja=1;
					break;
				}

				j=0;
				nr_val=p_buff;
				val_vechi=p_buff;
				nr_cas=7;
				nr_adaugate=p_end-p_buff;

				v_vector.secondbuff=(char *)realloc(v_vector.secondbuff,sizeof(char)*(strlen(superbuff)+1));
				strcpy(v_vector.secondbuff,superbuff);

				while(j<nr_adaugate)
				{
					x=0;
					contor1=contor2=0;
					//caracterele aflate inaintea gap-ului inainte de inserare

					if(val_vechi<pre)
					{
						for(i=0;i<val_vechi;i++)
						{
							SelectObject(hdc,CreateSolidBrush(RGB(255,255,0)));
			
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(256,256,0));
							Rectangle(hdc,x,530,x+47,586);
							letter=(const char *)(superbuff+i);
							SetBkColor(hdc, RGB(255,255,0));
							SetRect(&textRect, x, 530, x+47,586);
							DrawText(hdc,TEXT(letter),1,&textRect, DT_MODIFYSTRING|DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
							Sleep(100);
							//======================================marcarea casutei curente===========
							SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(0,0,255));
							Rectangle(hdc,x+48,530,x+47+48,586);
							Sleep(100);
							x=x+48;
						}
					}
					else
					{
						for(i=0;i<pre;i++)
						{
							SelectObject(hdc,CreateSolidBrush(RGB(255,255,0)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(256,256,0));
							Rectangle(hdc,x,530,x+47,586);

							letter=(const char *)(superbuff+val_vechi-pre+i);

							SetBkColor(hdc, RGB(255,255,0));
							SetRect(&textRect, x, 530, x+47,586);
							DrawText(hdc,TEXT(letter),1,&textRect, DT_MODIFYSTRING|DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
							//x=x+48;
							Sleep(100);
							//======================================marcarea casutei curente===========
							SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(0,0,255));
							Rectangle(hdc,x+48,530,x+47+48,586);
							Sleep(100);
							x=x+48;
							//=========================================================================
						}
					}
					//solved

					//afisarea succesiva  a cate unui caracter care a fost introdus
					nr_cas=7;
					for(cont=val_vechi-p_buff;cont<=j && i<28;i++,cont++)
					{
						nr_cas--;
						SelectObject(hdc,CreateSolidBrush(RGB(255,255,0)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(256,256,0));
						Rectangle(hdc,x,530,x+47,586);

						letter=(const char *)(superbuff+p_buff+cont);

						SetBkColor(hdc, RGB(255,255,0));
						SetRect(&textRect, x, 530, x+47,586);
						DrawText(hdc,TEXT(letter),1,&textRect, DT_MODIFYSTRING|DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
						//x=x+48;
						Sleep(100);
							//======================================marcarea casutei curente===========
						SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(0,0,255));
						Rectangle(hdc,x+48,530,x+47+48,586);
						Sleep(100);
						x=x+48;
							//=========================================================================
					}
					start=i;

					for(;i<start+nr_cas && i<28;i++)
					{
						SelectObject(hdc,CreateSolidBrush(RGB(255,0,0)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(256,256,0));
						Rectangle(hdc,x,530,x+47,586);
						SetBkColor(hdc, RGB(255,0,0));	
						SetRect(&textRect, x, 530, x+47,586);
						DrawText(hdc,TEXT(chd),-1,&textRect, DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
						//x=x+48;
						Sleep(100);
						//======================================marcarea casutei curente===========
						SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(0,0,255));
						Rectangle(hdc,x+48,530,x+47+48,586);
						Sleep(100);
						x=x+48;
						Sleep(100);
						//=========================================================================
					}
					//solved
					start=i;
					for(k=p_end+1;i<28;i++,k++)
					{
						if(k<strlen(superbuff))
							contor1++;//cate se afla afisabile in coada
						else
							contor2++;
					}

					for(i=start,var=0;i<28-contor1 && i<28;i++)
					{
						SelectObject(hdc,CreateSolidBrush(RGB(255,0,0)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(256,256,0));
						Rectangle(hdc,x,530,x+47,586);
						SetBkColor(hdc, RGB(255,0,0));	
						SetRect(&textRect, x, 530, x+47,586);
						DrawText(hdc,TEXT(chd),-1,&textRect, DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
						Sleep(100);
						//x=x+48;
						if(i<27)
						{
							//======================================marcarea casutei curente===========
							SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(0,0,255));
							Rectangle(hdc,x+48,530,x+47+48,586);
							Sleep(100);
							//=========================================================================
						}
						x=x+48;
					}
					for(k=p_end+1,var=0;i<28;i++,k++)
					{
						SelectObject(hdc,CreateSolidBrush(RGB(255,255,0)));
						hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
						SelectObject(hdc, hPen);
						SetBkColor(hdc, RGB(256,256,0));
						Rectangle(hdc,x,530,x+47,586);

						letter=(const char *)(superbuff+k);

						SetBkColor(hdc, RGB(255,255,0));
						SetRect(&textRect, x, 530, x+47,586);
						DrawText(hdc,TEXT(letter),1,&textRect, DT_MODIFYSTRING|DT_CENTER | DT_NOCLIP|DT_VCENTER|DT_SINGLELINE);
						Sleep(100);
						//x=x+48;	
						if(i<26)
						{
							//======================================marcarea casutei curente===========
							SelectObject(hdc,CreateSolidBrush(RGB(0,0,250)));
							hPen = CreatePen(PS_DOT,2,RGB(256,256,0));//perimetrul dreptunghiurilor
							SelectObject(hdc, hPen);
							SetBkColor(hdc, RGB(0,0,255));
							Rectangle(hdc,x+48,530,x+47+48,586);
							Sleep(100);
							//=========================================================================
						}
						x=x+48;
					}
					j++;
					//val_vechi++;
					if(nr_cas==0)
					{
						//j=j-7;
						//nr_adaugate-=7;
						val_vechi+=7;	
					}
					//solved, i am sure
				DeleteObject(hBrush);
				DeleteObject(hPen);
				GetStockObject(WHITE_BRUSH);
				GetStockObject(DC_PEN);
				}
			}
			break;
		case WM_SIZE:
			{

				if(GRAFIC_ACTIV)
				{
					SIZE_SAU_AF=0;
					SendMessage(hwnd,WM_COMMAND,ID_AFISARE,0);
				}
				if(buffer_desenat)
						SendMessage(hwnd,COMANDA,0,0);
				break;
			}
		case WM_CLOSE:
			DestroyWindow(hwnd);
		break;
		case WM_DESTROY:
			PostQuitMessage(0);
		break;
		default:
			return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

BOOL CALLBACK dialog1 (HWND hwnd_dialog, UINT msg, WPARAM wParam, LPARAM lParam)
{
	long long int ok,poz,numar,i,j,poz2;;
	char *linie=NULL,*pozitie=NULL;
	char *poz_stergere=NULL,*nr_de_caractere=NULL;
	struct list *man;
	LARGE_INTEGER tickPerSecond;
	LARGE_INTEGER t1,t2; // momente in executie	
	double diff=0;
	list *aux;

/////// Initializarea gap-buffer-ul

	TEXT_EDITOR.DIM=10;
	TEXT_EDITOR.dim_begin=0;
	TEXT_EDITOR.dim_end=0;
	TEXT_EDITOR.dim_gap=10;
	TEXT_EDITOR.buffer=(char*)malloc(sizeof(char)*10);
	TEXT_EDITOR.head_gap=TEXT_EDITOR.buffer;
	TEXT_EDITOR.after_gap=TEXT_EDITOR.buffer+9;
//=============================
	_int64 t_gap=0,t_liste=0;

	switch (msg)
	{
		case WM_INITDIALOG:
			return TRUE;
			break;
		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
					case IDC_BUTTON1:
						ok=returnare_continut(hwnd_dialog,&linie,IDC_EDIT1);
						if(ok==0)
						{
							MessageBox(hwnd,"Date nu au fost introduse corect !", "Inserare nereusita", MB_ICONWARNING);
							break;
						}
						ok=returnare_continut(hwnd_dialog,&pozitie,IDC_EDIT2);
						if(ok==0)
						{
							MessageBox(hwnd,"Pozitia nu a fost introdusa si va 1 BY DEFAULT !", "", MB_ICONWARNING);
							poz=1;
						}
						else
						{
							///verificare daca este numar corect introdus
							if(verificare_integer(pozitie))
								poz=atoi(pozitie);
							else
							{
								MessageBox(hwnd,"Pozitia nu este valida", "Inserare nereusita", MB_ICONWARNING);
								break;
							}
						}

						if(poz>TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end)
							poz=TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end+1;
						if(poz<0)
							break;
						if(caz==0)
						{
							caz=1;
							poz=1;
						}

	//-----------------------------------------------------------------------------------------
		//  adaugare pentru gap
						poz--;		//pozitia este de fapt mai mica intrucat indexarea incepe de la 0
						poz2=poz;

						p_buff=poz;
						p_end=poz+strlen(linie);

						QueryPerformanceCounter(&t1); 
						for(i=0;i<strlen(linie);i++)
						{
							if(linie[i+1])
								if(linie[i+1]=='\n')
									i++;
							insert_char(&TEXT_EDITOR,linie[i],poz2);
							poz2++;
						}
						QueryPerformanceCounter(&t2);
						t_gap=(t2.QuadPart-t1.QuadPart);	
						QueryPerformanceFrequency(&tickPerSecond);
						timp_gap+=(double)t_gap/(1000*((double)tickPerSecond.QuadPart/1000));
//=====================================================================================================
						//construirea superbuff-ului
						if(superbuff!=NULL)
							free(superbuff);
						superbuff=(char *)calloc(sizeof(char),(TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end+1));
						for(i=0;i<TEXT_EDITOR.dim_begin;i++)		
							superbuff[i]=TEXT_EDITOR.buffer[i];
						j=i;
						for(i=0;i<TEXT_EDITOR.dim_end;i++)
							superbuff[j++]=TEXT_EDITOR.after_gap[i];
						superbuff[j]='\0';
					SendMessage(hwnd,COMANDA,0,0);
	//=====================================================================================================
						// adaugare pentru lista 
						poz2=poz;

						QueryPerformanceCounter(&t1);
						aux=search_linie(prim,&poz2);
						for(i=0;i<strlen(linie);i++)
						{
							if(linie[i+1])
								if(linie[i+1]=='\n')
									i++;
							inserare_linked(linie[i],&poz2,&prim,&ultim,&aux);
						}
						QueryPerformanceCounter(&t2);
						t_liste=(double)(t2.QuadPart-t1.QuadPart);	
						QueryPerformanceFrequency(&tickPerSecond);
						timp_liste+=(double)t_liste/(1000*((double)tickPerSecond.QuadPart/1000));
			//			construire_vectori();
//=====================================================================================================================
						free(linie);
						free(pozitie);
						linie=NULL;
						pozitie=NULL;
						break;
				
				case IDC_BUTTON2:
					{
						ok=returnare_continut(hwnd_dialog,&poz_stergere,IDC_EDIT5);
						if(ok==0)
						{
							MessageBox(hwnd,"Date nu au fost introduse corect !", "Inserare nereusita", MB_ICONWARNING);
							break;
						}
						if(verificare_integer(poz_stergere))
							poz=atoi(poz_stergere);
						else
						{
							MessageBox(hwnd,"Pozitia nu este valida", "Inserare nereusita", MB_ICONWARNING);
							break;
						}

						ok=returnare_continut(hwnd_dialog,&nr_de_caractere,IDC_EDIT6);
						if(ok==0)
						{
							MessageBox(hwnd,"Date nu au fost introduse corect !", "Inserare nereusita", MB_ICONWARNING);
							break;
						}
						if(verificare_integer(nr_de_caractere))
							numar=atoi(nr_de_caractere);
						else
						{
							MessageBox(hwnd,"Numarul de caractere nu este valid.", "Inserare nereusita", MB_ICONWARNING);
							break;
						}

						poz--;
						poz2=poz;
//-------------------------------------------------------------------------------------------------------------
			// stregere pentru gap
						if(TEXT_EDITOR.dim_begin==0 && TEXT_EDITOR.dim_end==0)		//cazul in care nu s-a inserat inca nimic
						{
							MessageBox(hwnd,"Inca nu s-a inserat nimic", "Stergere nereusita", MB_ICONWARNING);
								break;
						}
						if(0<=poz && (TEXT_EDITOR.dim_begin + TEXT_EDITOR.dim_end)>=poz)		//cazul in care pozitia inserata se afla in interiorul textului
						{
							if(numar>(TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end-poz))   //cazul in care s-a introdus un numar de caracetere
								numar=TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end-poz;	// ce trebuie sters mai mare decat numarul de caractere din textul efectiv
						
							QueryPerformanceCounter(&t1);							
								for(i=0;i<numar;i++)
									stergere(&TEXT_EDITOR,poz);	
							QueryPerformanceCounter(&t2);
							t_gap=(t2.QuadPart-t1.QuadPart);	
							QueryPerformanceFrequency(&tickPerSecond);
							timp_gap+=(double)t_gap/(1000*((double)tickPerSecond.QuadPart/1000));
						}
						else
						{
							MessageBox(hwnd,"Pozitia inserata nu este valida", "Stergere nereusita", MB_ICONWARNING);
								break;
						}					
	//================================================================================================================
						//stergerea pentru liste
						QueryPerformanceCounter(&t1);
						struct list *linie_de_sters=search_linie(prim,&poz2);
						if(linie_de_sters!=NULL)				
							stergere(&linie_de_sters,poz2,numar,&prim);
						QueryPerformanceCounter(&t2);
						t_liste=(t2.QuadPart-t1.QuadPart);	
						QueryPerformanceFrequency(&tickPerSecond);
						timp_liste+=(double)t_liste/(1000*((double)tickPerSecond.QuadPart/1000));
	//================================================================================================================
			//			construire_vectori();
						//construirea superbuff-ului
						if(superbuff!=NULL)
							free(superbuff);
						superbuff=(char *)calloc(sizeof(char),(TEXT_EDITOR.dim_begin+TEXT_EDITOR.dim_end+1));
						for(i=0;i<TEXT_EDITOR.dim_begin;i++)		
							superbuff[i]=TEXT_EDITOR.buffer[i];
						j=i;
						for(i=0;i<TEXT_EDITOR.dim_end;i++)
							superbuff[j++]=TEXT_EDITOR.after_gap[i];
						superbuff[j]='\0';
				///======================================================
						free(poz_stergere);//reprezinta de fapt pozitia
						free(nr_de_caractere);//numarul de caractere de fapt
						poz_stergere=NULL;
						nr_de_caractere=NULL;
						break;
					}
				case IDC_BUTTON4:
					//timp_gap=0; timp_liste=0;
					if(*(&(TEXT_EDITOR.buffer))!=NULL)
					{
						free(TEXT_EDITOR.buffer);
						TEXT_EDITOR.buffer=NULL;
					}
					if(*(&(prim))!=NULL)
					{
						elibmem(&prim);
						prim=ultim=NULL;
					}
					SendMessage(hwnd,RESET_GRAFIC,0,0);
					EndDialog(hwnd_dialog,0);
					break;
					case IDC_BUTTON3:
					//timp_gap=0; timp_liste=0;
					if(*(&(TEXT_EDITOR.buffer))!=NULL)
					{
						free(TEXT_EDITOR.buffer);
						TEXT_EDITOR.buffer=NULL;
					}
					if(*(&(prim))!=NULL)
					{
						elibmem(&prim);
						prim=ultim=NULL;
					}
					SendMessage(hwnd,RESET_GRAFIC,0,0);
					EndDialog(hwnd_dialog,0);
					break;
				break;
				}
			}
		break;
		case WM_CLOSE:
			EndDialog(hwnd_dialog,0);
		break;
		 
		default:
			return FALSE;
		}
		return TRUE;
}

int returnare_continut(HWND hwnd,char **sir,int Box_id)
{
	int dim;
	dim=GetWindowTextLength(GetDlgItem(hwnd,Box_id));
	if (dim==0)
		return 0; 
	else
		if (dim>0)
		{
			(*sir)=(char*)malloc(sizeof(char)*(dim+1));
			GetDlgItemText(hwnd,Box_id,(*sir),dim+1);
		}
	return 1;
}

BOOL CALLBACK AFISARE_TEXT(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	switch(Message)
	{
		case WM_INITDIALOG:
			SetDlgItemText(hwnd, IDC_EDIT1P, superbuff);
		break;
		case WM_COMMAND:
			switch(LOWORD(wParam))
			{
			case IDOK:
				EndDialog(hwnd, 0);
			}
		break;
		case WM_CLOSE:
			EndDialog(hwnd, 0);
		break;
		default:
			return FALSE;
	}
	return TRUE;
}

BOOL CALLBACK dialog_rand(HWND hwnd_dialog_r, UINT Message, WPARAM wParam, LPARAM lParam)
{
	char *operatii,aux[50];
	int nr_operatii=0, nr_ins=0, nr_sterg=0, tot_ins=0, tot_sterg=0,x;
	//FILE *fd=fopen("out.txt","a");

	bool ok;

	switch (Message)
	{
		case WM_INITDIALOG:
			return TRUE;
			break;
		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
					case ID_OK_D2:
						ok=returnare_continut(hwnd_dialog_r, &operatii, IDC_POZITIE);
						if(ok==0)
						{
							MessageBox(hwnd_dialog_r,"Nu s-a introdus nimic","EROARE",MB_OK | MB_ICONERROR);
							break;
						}
						if(verificare_integer(operatii))
						{
							nr_operatii=atoi(operatii);
							if(random_main(hwnd_dialog_r,nr_operatii,&nr_ins,&nr_sterg,&tot_ins,&tot_sterg))
							{
								MessageBox(hwnd_dialog_r,"Operatii efectuate cu succes","Mesaj",MB_OK);
								itoa(nr_operatii,aux,10);
								free(operatii);
								operatii=NULL;
								operatii=(char *)malloc(sizeof(char)*(26+strlen(aux)));
								strcpy(operatii,"S-au efectuat ");
								strcat(operatii,aux);
								strcat(operatii," operatii:");
								x=strlen(operatii);
								operatii[x]='\n';
								operatii[x+1]=NULL;
								itoa(nr_ins,aux,10);
								x=strlen(operatii);
								operatii=(char *)realloc(operatii,sizeof(char)*(strlen(operatii)+strlen(aux)+26));
								strcat(operatii+x,aux);
								strcat(operatii," inserari cu un total de ");
								itoa(tot_ins,aux,10);
								operatii=(char *)realloc(operatii,sizeof(char)*(strlen(operatii)+strlen(aux)+11));
								strcat(operatii,aux);
								strcat(operatii,"caractere");
								x=strlen(operatii);
								operatii[x]='\n';
								operatii[x+1]=NULL;
								itoa(nr_sterg,aux,10);
								operatii=(char *)realloc(operatii,sizeof(char)*(strlen(operatii)+strlen(aux)+27));
								strcat(operatii,aux);
								strcat(operatii," stergeri cu un total de ");
								itoa(tot_sterg,aux,10);
								operatii=(char *)realloc(operatii,sizeof(char)*(strlen(operatii)+strlen(aux)+12));
								strcat(operatii,aux);
								strcat(operatii," caractere");
								MessageBox(hwnd_dialog_r,operatii,"Mesaj",MB_OK);
								free(operatii);
								EndDialog(hwnd_dialog_r,0);
							}

							break;
						}
						else
						{
							MessageBox(hwnd_dialog_r,"Nu s-a introdus un numar valid","EROARE",MB_OK | MB_ICONERROR);
							break;
						}
					case IDCANCEL:
						SendMessage(hwnd,RESET_GRAFIC,0,0);
						EndDialog(hwnd_dialog_r,0);
					break;
				}
			}
		break;
		case WM_CLOSE:
			EndDialog(hwnd_dialog_r,0);
		break;
		 
		default:
			return FALSE;
		}
		return TRUE;
}

